feat: replay scrollback history to boo ui views on attach#72
Conversation
A boo ui view's scrollback lived only in its local terminal and was built from output streamed while attached. Switching sessions destroys the view (and its scrollback) and creates a fresh one, and the daemon's attach replay (repaint) deliberately sends only the visible screen, so a just-switched-to view had nothing above the current screen to scroll up into. Replay the window's history to ui views on attach: - window.historyReplay: VT bytes that reproduce the scrollback HISTORY (rows above the visible screen) as a styled, scrolling stream, plus a full-screen flush so every history row lands in the canvas's scrollback before the repaint's erase, with no blank gap. Fed before repaint(), a fresh terminal ends up holding the same scrollback, viewport at bottom. - protocol.AttachPayload: the attach handshake now carries a `ui` flag (decodes a bare 4-byte size payload as non-ui for slack). - The daemon sends the history (chunked across output frames, since it can exceed max_payload) before the repaint, but only to ui clients. A plain `boo attach` is raw passthrough, where a history dump would spam the user's real terminal, so it stays history-free. Verified end to end: a ui attach receives scrolled-off history; a plain attach receives only the visible screen. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kylecarbs
left a comment
There was a problem hiding this comment.
Thanks for this, @BenLocal. I reviewed it and built/tested it end to end with Zig 0.15.2. The feature itself is well built and correct: the history reconstruction (serialize scrollback history as styled VT, reset SGR, scroll a full screen so every history row lands in the canvas scrollback before the repaint's erase, then repaint the visible screen) is sound and unit-tested, plain attach correctly stays history-free, and alt-screen sessions correctly yield no history.
Verification: zig fmt --check, zig build, zig build test (120), zig build test-integration (69), and zig build test-all -Doptimize=ReleaseSafe all pass.
Two things to address before merge:
-
Upgrade incompatibility. Widening attach to a 5-byte
AttachPayloadmeans a daemon started by a pre-upgrade binary (which decodes attach as a strict 4-byteSizePayload) rejects the new payload. After upgrading, a newboo ui/boo attachcan't attach to a pre-upgrade session, the client reportslost connection. I confirmed this against amaindaemon. Suggested fix: keep attach as the 4-byteSizePayloadand send a separateuimarker message before attaching; older daemons ignore the unknown message type and just attach with no history (graceful degradation). -
No integration test for the new path. The window-level unit test is great, but the daemon -> client replay and the plain-attach gating aren't covered by the PTY suite.
Rather than block on a round-trip, I pushed a follow-up that implements both on top of your commit (yours is preserved underneath): #75. Happy to fold it back in here or land it there, whichever you prefer.
Disclosure: this review was generated by Coder Agents on behalf of @kylecarbs.
Replays a session's scrollback history to boo ui views on attach, so a wheel-up can page output that scrolled off before the view attached (e.g. after switching sessions and back, or reattaching). Builds on #72 by @BenLocal with: - a backward-compatible `ui` marker message so older daemons attach with no history instead of rejecting the client, - a blank-hold until the attach repaint completes so a large replay never flashes partial scrollback, revealed incrementally so the post-attach write can't wedge an undrained ui on macOS, - PTY integration coverage for both the ui replay and the plain-attach (history-free) gating. Plain `boo attach` is unchanged: it stays raw passthrough and receives only the visible screen. Co-authored-by: benshi <807629978@qq.com> Generated by Coder Agents on behalf of @kylecarbs.
|
Thanks @BenLocal — this shipped in v0.5.22 🎉 We landed it via #75, which builds directly on your commit (preserved with you as a co-author) and adds a few things on top: a backward-compatible Closing this in favor of #75. Really appreciate the contribution! Generated by Coder Agents on behalf of @kylecarbs. |
|
Sorry for the pure LLM message above. The content above is accurate, and is fixed in the latest release. Thanks for opening this! |
A boo ui view's scrollback lived only in its local terminal and was built from output streamed while attached. Switching sessions destroys the view (and its scrollback) and creates a fresh one, and the daemon's attach replay (repaint) deliberately sends only the visible screen, so a just-switched-to view had nothing above the current screen to scroll up into.
Replay the window's history to ui views on attach:
uiflag (decodes a bare 4-byte size payload as non-ui for slack).boo attachis raw passthrough, where a history dump would spam the user's real terminal, so it stays history-free.Verified end to end: a ui attach receives scrolled-off history; a plain attach receives only the visible screen.